package com.ck.ips.core.interceptor;

import com.ck.common.SessionUser;
import com.ck.common.model.OperationResult;
import com.ck.core.annotation.ResourcePermissionRequired;
import com.ck.core.constant.ClientConstant;
import com.ck.core.constant.UserType;
import com.ck.core.context.UserContextHolder;
import com.ck.ips.service.sys.ModuleService;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
* @Description: 资源管理控制拦截器，判断用户是否有对该资源的访问权限
* @Author: hf
* @Date:    2019/4/15 10:24
* @Version: 1.0
*/
@Component
public class ResourceInterceptor implements HandlerInterceptor {
	private static final Logger logger = LoggerFactory.getLogger(ResourceInterceptor.class);

	@Autowired
	private ModuleService moduleService;

	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

		// options 跨域预检查请求不必拦截
		if( RequestMethod.OPTIONS.name().equals(request.getMethod()) ){
			return true;
		}

		try {
			if ( hasPermission(handler,request,response) ) {
				return true;
			}
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
		}

		return false;
	}


	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse respone, Object arg2, ModelAndView arg3)
			throws Exception {
		// DOING NOTHING
	}

	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse respone, Object arg2, Exception arg3)
			throws Exception {
		// DOING NOTHING
	}

	/**
	 * 客户端是否有访问权限
	 * @param handler
	 * @param response
	 * @return
	 */
	private boolean hasPermission(Object handler, HttpServletRequest request, HttpServletResponse response) throws Exception {
		if (handler instanceof HandlerMethod) {
 			HandlerMethod handlerMethod = (HandlerMethod) handler;
			ResourcePermissionRequired resourcePermissionRequired = handlerMethod.getMethod().getAnnotation(ResourcePermissionRequired.class);

			// 如果方法上的注解为空 则获取类的注解
			if (resourcePermissionRequired == null) {
				resourcePermissionRequired = handlerMethod.getMethod().getDeclaringClass().getAnnotation(ResourcePermissionRequired.class);
			}

			// 如果标记了需要验证，则判断权限
			if ( resourcePermissionRequired != null ) {

				// 当前登录用户信息
				SessionUser sessionUser = UserContextHolder.currentUser();

				// 非超管用户验证资源访问权限
				if ( !UserType.SUPER.name().equals(sessionUser.getUserType()) && !moduleService.resourceMatch(request.getRequestURI())) {
					response.getWriter().write(new ObjectMapper().writeValueAsString(new OperationResult(ClientConstant.CODE_PERMISSION_DENIED,"Authentication Failed")));
					response.setContentType("application/json;charset=utf-8");
					setCross(response);
					return false;

				}
			}
		}
		return true;
	}

	/**
	 * 设置跨域
	 *
	 * @param response 响应
	 */
	private void setCross(HttpServletResponse response) {
		response.setHeader("Access-Control-Allow-Origin", "*");
		response.addHeader("Access-Control-Allow-Credentials", "true");
		response.setHeader("Access-Control-Allow-Methods", "GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS, PATCH");
		response.addHeader("Access-Control-Allow-Headers",
				"Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers,token");
		response.setStatus(HttpStatus.OK.value());
	}
}
